home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
hard
/
hack
/
eprommerv2.lha
/
EPROMmer
/
eprommer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-03
|
15KB
|
705 lines
/*
* An adaption of EPROMmer.bas
* By Udi Finkelstein (C) 1990
*/
#include <stdio.h>
#include <stdarg.h>
#include "req/reqbase.h"
#include "req/req_protos.h"
#include "req/req.h"
/*
* So PowerWindows doesn't add a 'chip' keyword?? so what ...
*/
#define USHORTTMP USHORT
#undef USHORT
#define USHORT USHORTTMP chip
#include "EPROMmer.h"
#undef USHORT
#define USHORT USHORTTMP
/*
* Since I have blown PA0 on my machine, I have used one of the RS232
* signals instead, and used a 1489 receiver on the circuit instead of
* using PA0.
*/
#ifdef USE_RS232
#define OE 0x41
#else
#define OE 0x01
#endif
#define PGM 0x02
#define VOLTS12 (223 - 128)
#define VOLTS21 (223 - 64)
#define VOLTS25 (223 - 192)
/* PA2 = SEL */
#define Clock0 0
#define Clock1 4
unsigned char far EmemBase[0x10000];
char *EmemTop,*RamBot;
volatile unsigned char *ParPort = (volatile unsigned char *)0xbfe101;
volatile unsigned char *ParDDR = (volatile unsigned char *)0xbfe301;
volatile unsigned char *CtrlPort = (volatile unsigned char *)0xbfd000;
volatile unsigned char *CtrlDDR = (volatile unsigned char *)0xbfd200;
char *EpromType;
unsigned char volt_tbl[] = { VOLTS25, VOLTS25, VOLTS21, VOLTS21,
VOLTS12, VOLTS12, VOLTS12, VOLTS12, VOLTS12 };
/* PA0 = /OE, PA1 = /PGM */
unsigned char rp_tbl[] = { 0, 0, 0, PGM, PGM, PGM, 0, 0, 0 };
unsigned char wp_tbl[] = { OE+PGM, OE, OE, OE, OE, OE, OE, OE, OE };
unsigned char lp_tbl[] = { OE+PGM, OE+PGM, OE+PGM, OE+PGM, OE+PGM,
OE+PGM, OE+PGM, OE+PGM, OE+PGM };
unsigned char ip_tbl[] = { OE, OE+PGM, OE+PGM, OE+PGM, OE+PGM, OE+PGM,
OE+PGM, OE+PGM, OE+PGM };
unsigned char e_flag[] = { 1, 1, 1, 1, 1, 1, 1, 1, 0 };
unsigned short ad_tbl[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0x8000 };
short Wr50ms(unsigned char), WrIntel(unsigned char), WrFast(unsigned char),
WrEprommer(unsigned char);
struct Gadget *ag_tbl[] = { &FiftyMSGad, &FiftyMSGad, &FiftyMSGad,
&IntelGad, &IntelGad, &IntelGad, &IntelGad, &IntelGad, &FastGad };
short (*wa_tbl2[])(unsigned char) = { Wr50ms, WrIntel, WrEprommer, WrFast };
short (*WriteAlg)(unsigned char);
long size_tbl[] = { 2048, 4096, 4096, 8192, 8192, 16384, 32768, 65536, 32768 };
unsigned char VoltVal, ReadParam, WriteParam, LeaveParam, InhibitParam;
unsigned char Addr0, Addr1, Addr2, Addr3;
unsigned char Write1, Write2, Write3, Write4, Write5;
unsigned char Read0, Read1;
unsigned short LastAddr, AdParam;
LONG *RAMValInt, *RAMLowInt, *EPROMLowInt, *LengthInt;
struct Window *win;
struct RastPort *rp;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *ReqBase;
struct Gadget *ia, *old_type_gad, *old_alg_gad;
struct IntuiMessage *m;
struct MsgPort *tp;
struct timerequest *tr;
ULONG mc;
long Size;
short EPType = -1;
char Dir[DSIZE + 1], File[FCHARS + 1], FullPath[DSIZE+FCHARS+2];
struct ReqFileRequester frq ;
void UpdateLongInt(g)
struct Gadget *g;
{
SHORT pos;
struct StringInfo *si;
si = (struct StringInfo *)(g->SpecialInfo);
pos = RemoveGList(win, g, 1);
sprintf(si->Buffer, "%lu", si->LongInt);
si->NumChars = strlen(si->Buffer);
AddGList(win, g, pos, 1, NULL);
RefreshGList(g, win, NULL, 1);
}
/*
* Turn off the previously selected gadget, if there was one.
*/
void GadExclude(gad)
struct Gadget *gad;
{
if (gad) {
/* Turn off previous gadget */
gad->Flags ^= SELECTED;
SetAPen(rp, 0);
SetDrMd(rp, JAM1);
RectFill(rp, gad->LeftEdge, gad->TopEdge,
gad->LeftEdge + gad->Width, gad->TopEdge + gad->Height);
RefreshGList(gad, win, NULL, 1);
}
}
/*
* A general one gadget requester using req.library
*/
void SimpleRequest(char *str,...)
{
va_list ap;
struct TRStructure trs;
va_start(ap,str);
trs.Text = str;
trs.Controls = ap;
trs.Window = 0;
trs.MiddleText = 0;
trs.PositiveText = 0;
trs.NegativeText = "Resume";
trs.Title = "Ahem...";
trs.KeyMask = 0xFFFF;
trs.textcolor = 1;
trs.detailcolor = 2;
trs.blockcolor = 3;
trs.versionnumber = REQVERSION;
trs.Timeout = 0;
trs.AbortMask = 0;
trs.rfu1 = 0;
TextRequest(&trs);
va_end(ap);
}
/*
* A general two gadget requester using req.library
*/
short TwoGadRequest(char *str,...)
{
va_list ap;
struct TRStructure trs;
short res;
va_start(ap,str);
trs.Text = str;
trs.Controls = ap;
trs.Window = 0;
trs.MiddleText = 0;
trs.PositiveText = " OK ";
trs.NegativeText = "CANCEL";
trs.Title = "Ahem...";
trs.KeyMask = 0xFFFF;
trs.textcolor = 1;
trs.detailcolor = 2;
trs.blockcolor = 3;
trs.versionnumber = REQVERSION;
trs.Timeout = 0;
trs.AbortMask = 0;
trs.rfu1 = 0;
res = TextRequest(&trs);
va_end(ap);
return(res);
}
/*
* Timer initialization done here
*/
short OpenTimer()
{
if ((tp = CreatePort(0, 0)) == 0) return 1;
if ((tr = (struct timerequest *)CreateExtIO(tp, sizeof(struct timerequest)))
== NULL) return 1;
if (OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)tr, 0))
return 1;
}
/*
* Timer cleanup done here
*/
void CloseTimer(tr)
struct timerequest *tr;
{
if (tp) DeletePort(tp);
if (tr) {
CloseDevice((struct IORequest *)tr);
DeleteExtIO((struct IORequest *)tr);
}
}
/*
* A MicroHz precision delay routine
*/
void uDelay(delay)
unsigned long delay;
{
tr->tr_node.io_Command = TR_ADDREQUEST;
tr->tr_time.tv_secs = 0;
tr->tr_time.tv_micro = delay;
DoIO((struct IORequest *)tr);
}
void SetAddr(Address)
unsigned short Address;
{
LastAddr = Address;
*ParDDR = 255;
*ParPort = 253;
*CtrlPort = Addr0;
*ParPort = Address >> 8;
*CtrlPort = Addr1;
*ParPort = 254;
*CtrlPort = Addr2;
*ParPort = Address & 255;
*CtrlPort = Addr3;
}
void InitPorts()
{
*CtrlDDR = Clock1 + OE + PGM;
*CtrlPort = Clock0 + OE + PGM;
*ParDDR = 255;
*ParPort = 255;
*CtrlPort = Clock1 + OE + PGM;
*CtrlPort = Clock0 + OE + PGM;;
SetAddr(0);
}
void VPP_on()
{
*ParDDR = 255;
*ParPort = VoltVal;
*CtrlPort = Clock1;
}
void VPP_off()
{
*ParPort = 255;
*CtrlPort = LeaveParam + Clock0;
*CtrlPort = LeaveParam + Clock1;
*CtrlPort = LeaveParam + Clock0;
}
void ThatsIt()
{
SetAddr(0);
*CtrlDDR = 0;
*ParDDR = 0;
}
unsigned char ReadByte()
{
unsigned char DataIn;
/* If A15 is used for /WR, make sure it's high now - used for 62256 */
if (AdParam & 0x8000 & ~LastAddr) SetAddr(LastAddr | 0x8000);
/* port is now input */
*ParDDR = 0;
*CtrlPort = Read0;
DataIn = *ParPort;
*CtrlPort = Read1;
return DataIn;
}
void WriteByte(DataOut, delay)
unsigned char DataOut;
unsigned long delay;
{
/* If A15 is used for /WR, make sure it's low now - used for 62256 */
if (AdParam & 0x8000 & LastAddr) SetAddr(LastAddr & 0x7fff);
*ParDDR = 255;
*ParPort = VoltVal;
*CtrlPort = Write1;
*ParPort = DataOut;
*CtrlPort = Write2;
uDelay(delay);
*CtrlPort = Write3;
*ParPort = 255;
*CtrlPort = Write4;
*CtrlPort = Write5;
}
void SetCycleParams()
{
Write1 = InhibitParam + Clock1;
Write2 = WriteParam + Clock1;
Write3 = InhibitParam + Clock0;
Write4 = InhibitParam + Clock1;
Write5 = LeaveParam + Clock0;
Read0 = ReadParam + Clock0;
Read1 = LeaveParam + Clock0;
Addr0 = LeaveParam + Clock1;
Addr1 = LeaveParam + Clock0;
Addr2 = LeaveParam + Clock1;
Addr3 = LeaveParam + Clock0;
}
/*
* Write a single byte
*/
short WriteCycle(DataOut)
unsigned char DataOut;
{
unsigned char c;
/* Any bit set in DataOut which is already reset in the EPROM? */
c = ReadByte();
if (e_flag[EPType] && (~c & DataOut)) return 1;
/* Is data already identical? */
if (DataOut == c) return 0;
return (*WriteAlg)(DataOut);
}
/*
* The Eprommer algorythm - a variation on the intel algorythm.
*/
short WrEprommer(DataOut)
unsigned char DataOut;
{
short n;
unsigned long l;
/* Programming loop */
n = 0;
while(++n < 20) {
WriteByte(DataOut, 1000);
if (ReadByte() == DataOut) {
/* Overprogramming section */
l = n * 5000;
if (l > 20000) l = 20000;
WriteByte(DataOut, l);
return 0;
}
}
/* Too many retries, must be EPROM failure */
return 2;
}
/*
* The IntEligent programming algorythm algorythm.
*/
short WrIntel(DataOut)
unsigned char DataOut;
{
short n;
/* Programming loop */
n = 0;
while(++n < 15) {
WriteByte(DataOut, 1000);
if (ReadByte() == DataOut) {
/* Overprogramming section */
WriteByte(DataOut, n * 4000);
return 0;
}
}
/* Too many retries, must be EPROM failure */
return 2;
}
/*
* The fastest algorythm - use for RAMs only!
*/
short WrFast(DataOut)
unsigned char DataOut;
{
/* No loop! */
WriteByte(DataOut, 10);
if (ReadByte() == DataOut) return 0;
/* RAM failure */
return 2;
}
/*
* The basic 50ms pulse algorythm.
* Use for 2716, 2732 and 2732A chips which requires it. not all
* brands of chips require this slow algorythm (Intel does, TI don't).
*/
short Wr50ms(DataOut)
unsigned char DataOut;
{
/* No loop! */
WriteByte(DataOut, 50000);
if (ReadByte() == DataOut) return 0;
/* RAM failure */
return 2;
}
/*
* Read a file into the buffer
*/
void LoadFile()
{
FILE *fin;
frq.VersionNumber = REQVERSION;
frq.Dir = Dir;
frq.File = File;
frq.PathName = FullPath;
frq.Title = "Buffer Load";
frq.Flags = FRQCACHINGM|FRQLOADINGM|FRQHIDEWILDSM;
if (!FileRequester(&frq)) return;
if ((fin = fopen(FullPath, "r")) == NULL) {
SimpleRequest("Could not open input file (%s)!", FullPath);
return;
}
*LengthInt = fread(EmemBase + *RAMLowInt, 1, 0x10000 - *RAMLowInt, fin);
SimpleRequest("We read %ld bytes", *LengthInt);
UpdateLongInt(&Length);
fclose(fin);
}
/*
* Save a part of the buffer to disk
*/
void SaveFile()
{
FILE *fin;
LONG len;
frq.VersionNumber = REQVERSION;
frq.Dir = Dir;
frq.File = File;
frq.PathName = FullPath;
frq.Title = "Buffer Save";
frq.Flags = FRQCACHINGM|FRQLOADINGM|FRQHIDEWILDSM;
if (!FileRequester(&frq)) return;
if ((fin = fopen(FullPath, "w")) == NULL) {
SimpleRequest("Could not open output file!");
return;
}
len = fwrite(EmemBase + *RAMLowInt, 1, *LengthInt, fin);
if (len == *LengthInt)
SimpleRequest("We wrote %ld bytes", len);
else
SimpleRequest("We wrote only %ld bytes Instead of %ld bytes",
len, *LengthInt);
fclose(fin);
}
/*
* Read the EPROM
*/
void ReadEPROM()
{
unsigned short addr, len;
unsigned char *c;
if (EPType == -1) {
SimpleRequest("You must select an EPROM type first!");
return;
}
len = *LengthInt;
addr = *EPROMLowInt;
c = &EmemBase[*RAMLowInt];
while (len--) {
SetAddr(addr++);
*c++ = ReadByte();
}
SimpleRequest("We read %ld bytes", *LengthInt);
}
/*
* Compare the EPROM with the RAM buffer
*/
void CompareEPROM()
{
unsigned short addr, len;
unsigned char *c, ce, cr;
if (EPType == -1) {
SimpleRequest("You must select an EPROM type first!");
return;
}
len = *LengthInt;
addr = *EPROMLowInt;
c = &EmemBase[*RAMLowInt];
while (len--) {
SetAddr(addr++);
if ((cr = *c++) != (ce = ReadByte()))
if (!TwoGadRequest("Offset %ld, EPROM:%02lx RAM:%02lx",
addr - *EPROMLowInt - 1, ce, cr)) return;
}
SimpleRequest("We compared %ld bytes", *LengthInt);
}
/*
* Make sure EPROM is empty
*/
void CheckEPROM()
{
unsigned long addr;
if (EPType == -1) {
SimpleRequest("You must select an EPROM type first!");
return;
}
for (addr = 0; addr < Size;) {
SetAddr((unsigned short)(addr++));
if (ReadByte() != 255) {
SimpleRequest("EPROM contains data at %ld!", addr - 1);
return;
}
}
SimpleRequest("EPROM is empty");
}
/*
* Program the EPROM
*/
void ProgramEPROM()
{
unsigned short addr, len;
unsigned char *c;
if (EPType == -1) {
SimpleRequest("You must select an EPROM type first!");
return;
}
len = *LengthInt;
addr = *EPROMLowInt;
c = &EmemBase[*RAMLowInt];
while (len--) {
SetAddr(addr++);
switch (WriteCycle(*c++)) {
case 2:
SimpleRequest("Verify error at EPROM address %d", addr - 1);
return;
case 1:
SimpleRequest("EPROM already has data at address %d", addr - 1);
return;
}
}
SimpleRequest("We programmed %ld bytes", *LengthInt);
}
/*
* free every resource we might have allocated
*/
void cleanup(s)
char *s;
{
ThatsIt();
PurgeFiles(&frq);
if (s) Write(Output(), s, strlen(s));
if (tp) CloseTimer(tr);
if (win) CloseWindow(win);
if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
if (GfxBase) CloseLibrary((struct Library *)GfxBase);
if (ReqBase) CloseLibrary(ReqBase);
exit(0);
}
main()
{
/*
* Open all libraries, as well as the program's window
*/
if (!(IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 33L)))
cleanup("No intuition.library!\n");
if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 33L)))
cleanup("No graphics.library!\n");
if (!(ReqBase = OpenLibrary("req.library", 0L)))
cleanup("No req.library!\n");
if (!(win = OpenWindow(&NewWindowStructure1)))
cleanup("No window!\n");
rp = win->RPort;
/* Initialization for timer */
if (OpenTimer()) cleanup("No timer!");
/*
* Warning! due to a Lattice bug, we can't initialize these variables while
* they're defined, even though it's value is known at the time. They get
* initialized, but with the wrong values. Instead, we initialize them at
* run time.
*/
RAMLowInt = &(((struct StringInfo *)(RAMLow.SpecialInfo))->LongInt);
RAMValInt = &(((struct StringInfo *)(RAMVal.SpecialInfo))->LongInt);
EPROMLowInt = &(((struct StringInfo *)(EPROMLow.SpecialInfo))->LongInt);
LengthInt = &(((struct StringInfo *)(Length.SpecialInfo))->LongInt);
/* Update display */
UpdateLongInt(&RAMLow);
UpdateLongInt(&Length);
UpdateLongInt(&EPROMLow);
/* Initialize hardware */
InitPorts();
/*
* Event loop
*/
while (1) {
Wait(1L << (win->UserPort->mp_SigBit));
while (m = (struct IntuiMessage *)GetMsg(win->UserPort)) {
ia = (struct Gadget *)m->IAddress;
mc = m->Class;
ReplyMsg((struct Message *)m);
if (mc == CLOSEWINDOW) {
SimpleRequest("Please remove the EPROM now");
cleanup(NULL);
} else if (mc == GADGETUP) {
if (ia == &LoadGad) LoadFile();
else if (ia == &SaveGad) SaveFile();
else if (ia == &ReadGad) ReadEPROM();
else if (ia == &CheckGad) CheckEPROM();
else if (ia == &ProgramGad) ProgramEPROM();
else if (ia == &CompareGad) CompareEPROM();
else if (ia == &VPPGad) {
VPP_on();
SimpleRequest("VPP on now, press OK to turn it off");
VPP_off();
} else if (ia == &ReadByteGad) {
*RAMValInt = EmemBase[*RAMLowInt];
UpdateLongInt(&RAMVal);
} else if (ia == &WriteByteGad) {
EmemBase[*RAMLowInt] = (*RAMValInt &= 255);
UpdateLongInt(&RAMVal);
}
} else if (mc == GADGETDOWN) {
if ((LONG)(ia->UserData) & 0x200) {
/* get EPROM type */
EPType = (unsigned char)(ia->UserData);
/* set EPROM parameters */
Size = size_tbl[EPType];
VoltVal = volt_tbl[EPType];
ReadParam = rp_tbl[EPType];
WriteParam = wp_tbl[EPType];
InhibitParam = ip_tbl[EPType];
AdParam = ad_tbl[EPType];
*CtrlPort = LeaveParam = lp_tbl[EPType];
SetCycleParams();
/* turn off old gad */
GadExclude(old_type_gad);
old_type_gad = ia;
/* inform user */
SimpleRequest("Check for correct Personality Module");
/* fake a gadget event to set the defalut algorythm for the new type */
ia = ag_tbl[EPType];
/* Use GadExclude to turn the new gadget ON! */
GadExclude(ia);
/* Fall into the algorythm gadget's code to turn old gad off */
}
if ((LONG)(ia->UserData) & 0x100) {
WriteAlg = wa_tbl2[(unsigned char)(ia->UserData)];
GadExclude(old_alg_gad);
old_alg_gad = ia;
}
}
}
}
}